home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume91
/
utilitys
/
ed3_1_1
/
part04
/
sysgr.c
Wrap
C/C++ Source or Header
|
1991-11-07
|
25KB
|
1,068 lines
/*
Graphic initialization/cleanup for the 3D editor, ED3
Amiga-specific
10-18-91 added minimal memory-management for menus and gadgets
10-13-91 rem ShowGetLong and ShowThreeGadText
added native Intuition window/gadget drivers
09-02-91 check if the mouse hasn't moved far, in addition to DoubleClick
08-28-91 added Cut, Copy etc. menu items
08-24-91 ability to specify gadgets as non-selectable
08-23-91 now uses the system default font for gadgets, even on workbench
moved Save, Quit etc. from gadgets to menus
added toggle_menuitem()
08-10-91 added dynamic menu functions
08-08-91 changed clipping method
02-26-91 removed arp file requestor code
added reqlib code
*/
#include <intuition/intuition.h> /* includes clip, layers, rastport->gfx, view */
#include <exec/lists.h>
#include <exec/memory.h>
#include <graphics/gfxmacros.h>
#include <graphics/regions.h>
#include <exec/libraries.h>
#include <libraries/dosextens.h>/* For the process structure definition. */
#include <libraries/dos.h> /* we use a FileInfoBlock */
#include <libraries/reqbase.h>
#ifdef LATTICE
#include <proto/intuition.h>
#include <proto/graphics.h>
#else
#include <functions.h>
struct GfxBase *GfxBase = 0L;
struct IntuitionBase *IntuitionBase = 0L;
#endif
struct ReqLib *ReqBase = 0L;
#include <stdio.h>
#include "ed3.h" /* funtion defs, #defines, typedefs */
#define MAXPATH ( (FCHARS * 10) + DSIZE + 1) /* Size of a pathname */
#define K_shift 0x60
#define MAX_REMEMBERS 500
struct Process *myprocess = NULL;
APTR olderrorwindow;
struct FileRequester MyFileReqStruct;
char filename[FCHARS];
char directoryname[DSIZE];
char answerarray[DSIZE+FCHARS];
struct Screen *screen = NULL;
struct Window *window = NULL, *window2 = NULL;
struct RastPort *rp = NULL, /* RastPort of main editing window */
*screen_rport, /* RastPort of underlying screen */
*rp2 = NULL; /* RastPort of the small communication window */
struct ViewPort *vp = NULL;
struct Layer *my_layer;
struct TextAttr default_ta[1];
int active_text; /* id of the active text gadget; 0 if none */
int win2_mempoint;
typedef struct
{
long bytes;
void *memory;
} Remember;
Remember remember_mem[MAX_REMEMBERS];
int members = 0;
#define PALETTES 10
#define MAX_GADGETS 50
UWORD palette[PALETTES][4] =
{
{ 0x999, 0x000, 0xfff, 0xff0 },
{ 0xa98, 0x310, 0xfed, 0xfa0 },
{ 0xa88, 0x311, 0xfdd, 0xf66 },
{ 0x8a8, 0x020, 0xdfd, 0x0e0 },
{ 0x6a9, 0x021, 0xbfd, 0x0f7 },
{ 0x599, 0x021, 0xbfe, 0x0fe },
{ 0x69a, 0x012, 0xbef, 0x0cf },
{ 0x68a, 0x012, 0xcdf, 0x07f },
{ 0xa8a, 0x202, 0xfef, 0xfaf },
{ 0xb97, 0x321, 0xfed, 0x0f0 },
};
UWORD mypens[] =
{
0, /* detail */
1, /* block */
1, /* text */
2, /* shine */
1, /* shadow */
3, /* hifill */
1, /* hifilltext */
0, /* background */
3, /* hilighttext */
~0, /* TERMINATOR! */
};
struct TagItem mytags[2];
struct ExtNewScreen NS =
{
0,0,0,STDSCREENHEIGHT, /* filled in later*/
2, /* depth */
0, 0, /* detail, block */
HIRES|LACE,CUSTOMSCREEN | NS_EXTENDED,
NULL,NULL,NULL,NULL
};
struct NewWindow newwindow =
{
0, 0, 0, 0, /* filled in later */
0, 0,
0, /* filled in later */
0, /* filled in later */
NULL, NULL, NULL, NULL, NULL,
0, 0, 0, 0, 0
};
int font_w, font_h, baseline; /* size of system default font */
int titlefont_w, titlefont_h; /* size of font used in the screen title (and menus) */
int sys_white, sys_black, sys_medium, sys_bright;
int screen_depth;
int wb_width, wb_height; /* size of workbench screen */
int window_edge; /* number of pixels to account for the window edge */
int which_pal = 0, shift_key;
int win2_row, win2_col;
UWORD *amy_cmap = 0L;
int menu_count[10] = {0,0,0,0,0,0,0,0,0,0};
struct Menu *head_menu = 0L, *last_menu = 0L;
int gadget_count = 0, gadget_height, gadget_spacing;
struct Gadget *gadget_array[MAX_GADGETS];
/* these are for changing the values of toggleable menu items */
struct MenuItem *mi_dtool, *mi_cross, *mi_coord;
void open_stuff(depth, title)
short depth;
char *title;
{
struct Screen wbdata;
struct RastPort temp_rp; /* used to find font size */
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0);
if (!(ReqBase = (struct ReqLib *)OpenLibrary("req.library", 0L)))
sys_exit("Couldn't find the req library. Is it in your libs: directory?");
if (!(GetScreenData((char *)&wbdata, sizeof(struct Screen),
WBENCHSCREEN, NULL)))
sys_exit("unable to get screen info.");
wb_width = wbdata.ViewPort.DWidth;
wb_height = wbdata.ViewPort.DHeight;
InitRastPort(&temp_rp); /* find system font */
font_w = temp_rp.TxWidth;
font_h = temp_rp.TxHeight;
baseline = temp_rp.TxBaseline;
AskFont(&temp_rp, default_ta);
gadget_height = font_h + 2;
newwindow.Flags =
WFLG_ACTIVATE |
WFLG_SMART_REFRESH |
WFLG_REPORTMOUSE |
WFLG_RMBTRAP;
newwindow.IDCMPFlags =
IDCMP_MOUSEBUTTONS |
IDCMP_VANILLAKEY |
IDCMP_MOUSEMOVE |
IDCMP_MENUPICK |
IDCMP_GADGETUP,
sys_medium = 0;
sys_bright = 3;
if (flags.display_type & DF_WORKBENCH)
setup_for_workbench(&wbdata);
else
setup_for_custom_screen(depth, title);
colors.point = sys_white;
colors.titleb = sys_black;
colors.face = colors.box = colors.titlea = sys_bright;
colors.erase = sys_black;
newwindow.Width = sxmax;
newwindow.Height = symax;
newwindow.DetailPen = sys_white;
newwindow.BlockPen = sys_medium;
newwindow.Title = (UBYTE *)title;
edit_miny = titlefont_h + 4;
sxmax--;
symax--;
if (flags.display_type & DF_WORKBENCH) /* allow for window border */
{
sxmax -= 4;
symax -= 2;
}
x_center = edit_minx + (sxmax - edit_minx)/2;
y_center = edit_miny + (symax - edit_miny)/2;
if ((window = OpenWindow(&newwindow)) == NULL) sys_exit("no window");
rp = window->RPort;
if (symax < 300)
gadget_spacing = font_h + 2;
else
gadget_spacing = font_h + 3;
add_all_menus();
add_all_gadgets();
myprocess = (struct Process *)FindTask((char *)0);
olderrorwindow = myprocess->pr_WindowPtr;
myprocess->pr_WindowPtr = (APTR)window;
}
void setup_for_workbench(wbdata)
struct Screen *wbdata;
{
unsigned short color1, color2;
screen_rport = &(wbdata->RastPort);
screen_depth = wbdata->BitMap.Depth;
titlefont_h = wbdata->RastPort.TxHeight;
titlefont_w = wbdata->RastPort.TxWidth;
amy_cmap = (UWORD *)(wbdata->ViewPort.ColorMap->ColorTable);
sxmax = wb_width - 10;
symax = wb_height - 10;
newwindow.Screen = 0L;
newwindow.Type = WBENCHSCREEN;
newwindow.IDCMPFlags |= IDCMP_CLOSEWINDOW;
newwindow.Flags |= (WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET);
/* figure out the color scheme for this screen */
color1 = amy_cmap[1];
color2 = amy_cmap[2];
color1 = ((color1 & 0xf00) >> 8) + ((color1 & 0x0f0) >> 4) + (color1 & 0x00f);
color2 = ((color2 & 0xf00) >> 8) + ((color2 & 0x0f0) >> 4) + (color2 & 0x00f);
if (color1 > color2)
{
sys_white = 1;
sys_black = 2;
}
else
{
sys_white = 2;
sys_black = 1;
}
window_edge = 5;
}
void setup_for_custom_screen(depth, title)
int depth;
char *title;
{
sys_white = 2;
sys_black = 1;
NS.Width = wb_width;
NS.Depth = depth;
screen_depth = depth;
NS.DetailPen = sys_black;
NS.BlockPen = sys_white;
if (flags.display_type & DF_MED_RES)
NS.ViewModes = HIRES;
else
NS.ViewModes = HIRES | LACE;
mytags[0].ti_Tag = SA_Pens;
mytags[0].ti_Data = (ULONG) mypens;
mytags[1].ti_Tag = TAG_DONE;
mytags[1].ti_Data = NULL;
NS.Extension = mytags;
NS.DefaultTitle = (UBYTE *)title;
screen = (struct Screen *) OpenScreen(&NS);
if (!screen) sys_exit("Can't open screen\n");
screen_rport = &(screen->RastPort);
titlefont_h = screen_rport->TxHeight;
titlefont_w = screen_rport->TxWidth;
vp = &(screen->ViewPort);
amy_cmap = (UWORD *)screen->ViewPort.ColorMap->ColorTable;
sxmax = screen->Width;
symax = screen->Height;
if (!(flags.display_type & DF_SYS_PALETTE))
LoadRGB4(vp, palette[0], 1L<<depth);
newwindow.Screen = screen;
newwindow.Type = CUSTOMSCREEN;
newwindow.Flags |= (BORDERLESS | BACKDROP);
window_edge = 1;
}
void sys_attach_menus()
{
SetMenuStrip(window, head_menu);
}
void sys_refresh_gadgets()
{
RefreshGadgets(window->FirstGadget, window, NULL);
}
void add_gadget(string, gflags)
char *string;
int gflags;
{
int x, y, width;
x = window_edge;
y = edit_miny + 1 + (gadget_count * gadget_spacing);
width = (GADX - 9) - window_edge;
add_boolean_gadget(window, x, y, width, string, gflags, gadget_count + 1, 0);
gadget_count++;
}
void add_boolean_gadget(wind, x, y, width, string, gflags, id, draw)
struct Window *wind;
int x, y, width;
char *string;
int gflags;
int id;
int draw;
{
struct IntuiText *nt;
struct Gadget *ng;
int len = strlen(string), pix_width;
struct Border *border;
char *buf;
if (id > MAX_GADGETS) return;
nt = (struct IntuiText *)mem_alloc(sizeof(struct IntuiText));
ng = (struct Gadget *)mem_alloc(sizeof(struct Gadget));
buf = (char *)mem_alloc(len + 1);
strcpy(buf, string);
pix_width = len * font_w;
border = create_shadow_border(width, gadget_height, 1);
nt->FrontPen = 1;
nt->BackPen = 0;
nt->DrawMode = JAM2;
nt->LeftEdge = (width - pix_width)/2; /* centered text */
nt->TopEdge = 1;
if (flags.display_type & DF_WORKBENCH)
nt->ITextFont = default_ta; /* default font */
else
nt->ITextFont = NULL; /* default font */
nt->IText = buf;
nt->NextText = 0L;
ng->NextGadget = 0L;
ng->LeftEdge = x;
ng->TopEdge = y;
ng->Width = width;
ng->Height = gadget_height;
ng->Activation = GACT_RELVERIFY | GACT_IMMEDIATE;
ng->GadgetType = GTYP_BOOLGADGET;
if (gflags & GF_NOSELECT)
{
ng->GadgetRender = (APTR)0;
ng->Flags = GFLG_GADGHNONE; /* don't highlight */
}
else
{
ng->GadgetRender = (APTR)border;
ng->Flags = GFLG_GADGHCOMP;
}
ng->SelectRender = NULL;
ng->GadgetText = nt;
ng->MutualExclude = 0L;
ng->SpecialInfo = NULL;
ng->GadgetID = id;
ng->UserData = NULL;
AddGadget(wind, ng, (UWORD)~0); /* enforce append to list */
if (draw) /* draw this new (final) gadget */
RefreshGadgets(ng, wind, 0L);
gadget_array[id] = ng;
}
void add_long_gadget(wind, x, y, width, value, id, draw)
struct Window *wind;
int x, y;
int width;
long value;
int id;
int draw;
{
struct Gadget *ng;
struct StringInfo *nsi;
struct Border *border;
char *buf;
if (id > MAX_GADGETS) return;
border = create_shadow_border(width, font_h, 0);
ng = (struct Gadget *)mem_alloc(sizeof(struct Gadget));
nsi = (struct StringInfo *)mem_alloc(sizeof (struct StringInfo));
buf = (char *)mem_alloc(16);
sprintf(buf, "%ld", value);
nsi->Buffer = buf;
nsi->UndoBuffer = NULL;
nsi->BufferPos = strlen(buf);
nsi->MaxChars = 16;
nsi->DispPos = 0;
nsi->Extension = NULL;
nsi->LongInt = value;
nsi->AltKeyMap = NULL;
ng->NextGadget = 0L;
ng->LeftEdge = x;
ng->TopEdge = y;
ng->Width = width;
ng->Height = font_h;
ng->Activation = GACT_STRINGLEFT | GACT_LONGINT | GACT_RELVERIFY | GACT_IMMEDIATE;
ng->GadgetType = GTYP_STRGADGET;
ng->GadgetRender = (APTR)border;
ng->Flags = GFLG_GADGHCOMP;
ng->SelectRender = NULL;
ng->GadgetText = NULL;
ng->MutualExclude = 0L;
ng->SpecialInfo = nsi;
ng->GadgetID = id;
ng->UserData = NULL;
AddGadget(wind, ng, (UWORD)~0); /* enforce append to list */
if (draw) /* draw this new (final) gadget */
RefreshGadgets(ng, wind, 0L);
gadget_array[id] = ng;
}
/* create a "shadow" 3D box for use around a gadget */
struct Border *create_shadow_border(width, height, inside)
int width, height;
int inside; /* if TRUE, put the border inside the gadget, else surrounding */
{
struct Border *border_1, *border_2;
short *vectors_1, *vectors_2;
int x0, x1, y0, y1;
border_1 = (struct Border *)mem_alloc(sizeof (struct Border));
border_2 = (struct Border *)mem_alloc(sizeof (struct Border));
vectors_1 = (short *)mem_alloc(6 * sizeof(short));
vectors_2 = (short *)mem_alloc(6 * sizeof(short));
x0 = 0;
x1 = width-1;
y0 = 0;
y1 = height-1;
if (!inside)
{
x0--;
x1++;
y0--;
y1++;
}
vectors_1[0] = x0;
vectors_1[1] = y1;
vectors_1[2] = x0;
vectors_1[3] = y0;
vectors_1[4] = x1;
vectors_1[5] = y0;
vectors_2[0] = x0+1;
vectors_2[1] = y1;
vectors_2[2] = x1;
vectors_2[3] = y1;
vectors_2[4] = x1;
vectors_2[5] = y0+1;
border_1->LeftEdge = 0;
border_1->TopEdge = 0;
border_1->FrontPen = sys_white;
border_1->BackPen = 0;
border_1->DrawMode = JAM1;
border_1->Count = 3;
border_1->XY = vectors_1;
border_1->NextBorder = NULL;
*border_2 = *border_1;
border_2->XY = vectors_2;
border_2->NextBorder = border_1;
border_2->FrontPen = sys_black;
return border_2;
}
void add_menu(name)
char *name;
{
struct Menu *newmenu;
int len = strlen(name);
char *buf;
newmenu = (struct Menu *)mem_alloc(sizeof(struct Menu));
buf = (char *)mem_alloc(len + 1);
strcpy(buf, name);
newmenu->NextMenu = 0L;
newmenu->LeftEdge = 0;
newmenu->TopEdge = 0;
newmenu->Width = len * titlefont_w + 8;
newmenu->Height = titlefont_h;
newmenu->Flags = MENUENABLED;
newmenu->MenuName = buf;
newmenu->FirstItem = 0L;
/* add to linked list */
if (!head_menu)
{
newmenu->LeftEdge = 0L;
head_menu = newmenu;
}
else
{
newmenu->LeftEdge = last_menu->LeftEdge + last_menu->Width + 6;
last_menu->NextMenu = newmenu;
}
last_menu = newmenu;
}
struct MenuItem *add_menu_item(menu_num, name, mflags, shortcut)
char *name;
int menu_num, mflags;
char shortcut;
{
struct IntuiText *newtext;
struct MenuItem *newitem, *lastitem;
struct Menu *menu;
int len = strlen(name), mcount;
char *buf;
/* find the menu we're going to attach this item to */
menu = head_menu;
for (mcount = 0; mcount < menu_num; mcount++) menu = menu->NextMenu;
newtext = (struct IntuiText *)mem_alloc(sizeof(struct IntuiText));
newitem = (struct MenuItem *)mem_alloc(sizeof(struct MenuItem));
buf = (char *)mem_alloc(strlen(name) + 1);
strcpy(buf, name);
newtext->FrontPen = 2;
newtext->BackPen = 1;
newtext->DrawMode = JAM1;
newtext->LeftEdge = 0;
newtext->TopEdge = 0;
if (flags.display_type & DF_WORKBENCH)
newtext->ITextFont = default_ta; /* default font */
else
newtext->ITextFont = NULL; /* default font */
newtext->IText = buf;
newtext->NextText = 0L;
newitem->NextItem = 0L;
newitem->LeftEdge = 0;
newitem->TopEdge = menu_count[menu_num] * (font_h + 1);
newitem->Width = len * font_w + 4;
newitem->Height = font_h + 1;
newitem->Flags = ITEMTEXT+HIGHCOMP;
newitem->MutualExclude = 0;
newitem->ItemFill = (APTR)newtext;
newitem->SelectFill = 0L;
newitem->Command = shortcut;
newitem->SubItem = 0L;
newitem->NextSelect = 0L;
if (!(mflags & MO_NOTENABLED))
newitem->Flags |= ITEMENABLED;
if (mflags & MO_TOGGLE)
{
newitem->Flags |= (CHECKIT | MENUTOGGLE);
newitem->Width += CHECKWIDTH + 1;
newtext->LeftEdge += CHECKWIDTH + 1;
if (mflags & MO_CHECKED)
newitem->Flags |= CHECKED;
}
if (shortcut)
{
newitem->Flags |= COMMSEQ;
newitem->Width += 40;
}
menu->Height += (titlefont_h + 1);
/* add to linked list */
lastitem = menu->FirstItem;
if (!lastitem)
{
menu->FirstItem = newitem; /* first item */
}
else /* find the first item */
{
while (lastitem->NextItem) lastitem = lastitem->NextItem;
lastitem->NextItem = newitem;
}
menu_count[menu_num]++; /* one more item for this menu */
return newitem;
}
void toggle_menuitem(which_menu, which_item)
int which_menu, which_item;
{
struct Menu *m;
struct MenuItem *mi;
int i1;
m = head_menu;
for (i1 = 0; i1 < which_menu; i1++) m = m->NextMenu;
mi = m->FirstItem;
for (i1 = 0; i1 < which_item; i1++) mi = mi->NextItem;
mi->Flags ^= CHECKED;
}
void sys_exit(s)
char *s;
{
unsigned short i;
for (i = 0; i < polys; i++) kill_poly(i);
free_arrays();
if (myprocess) myprocess->pr_WindowPtr = olderrorwindow;
if (window)
{
ClearMenuStrip(window);
CloseWindow(window);
}
clear_remember(0);
if (screen) CloseScreen(screen);
if (ReqBase)
{
PurgeFiles(&MyFileReqStruct); /* Only necessary if the FRQCACHINGM flag */
/* is set in the file requester structure. */
CloseLibrary(ReqBase);
}
if (GfxBase) CloseLibrary(GfxBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (*s) puts(s);
exit (0);
}
void enable_menus(on)
char on;
{
if (on) window->Flags &= ~RMBTRAP;
else window->Flags |= RMBTRAP;
}
void wait_for_message()
{
Wait(1L<<window->UserPort->mp_SigBit);
}
long last_secs = 0, last_micros = 0; /* Time of last button click */
short last_x, last_y; /* pointer xy at time of last click */
void handle_messages()
{
ULONG class;
USHORT code, qual, mflag = 0;
struct Gadget *gadget;
long secs, micros;
coord newx, newy;
struct IntuiMessage *message;
newx = window->MouseX;
newy = window->MouseY;
while (message = (struct IntuiMessage *)GetMsg(window->UserPort))
{
newx = message->MouseX;
newy = message->MouseY;
class = message->Class;
if (class == IDCMP_MOUSEMOVE) /* quickly handle mousemoves */
{
mflag = 1;
ReplyMsg(message);
continue;
}
code = message->Code;
qual = message->Qualifier;
gadget = (struct Gadget *)(message->IAddress);
secs = message->Seconds;
micros = message->Micros;
ReplyMsg(message);
switch (class)
{
case IDCMP_MOUSEBUTTONS:
switch(code)
{
case SELECTDOWN:
case MENUDOWN:
if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_LSHIFT))
shift_key = 1; /* shift key down */
else
shift_key = 0; /* shift key up */
if (my > edit_miny && mx > edit_minx) /* in the editing area */
{
code = (code == MENUDOWN ? 1 : 0);
if (mode == M_DIST || mode == M_SELE || mode == M_MOVP)
{
if (DoubleClick(last_secs, last_micros, secs, micros)
&& abs(last_x - mx) < 5 && abs(last_y - my) < 5)
code |= MF_DOUBLE;
}
if (shift_key) code |= MF_SHIFTED;
mouse_down(code);
last_secs = secs;
last_micros = micros;
last_x = mx;
last_y = my;
}
break;
case SELECTUP:
case MENUUP: mouse_up(); break;
}
break;
case IDCMP_VANILLAKEY:
switch (code)
{
case '`':
which_pal++;
if (which_pal == PALETTES) which_pal = 0;
LoadRGB4(vp, palette[which_pal], 4);
break;
default:
handle_key(code); break;
}
break;
case IDCMP_MENUPICK: sys_handle_menu(code); break;
case IDCMP_GADGETUP: handle_gadget(gadget->GadgetID); break;
case IDCMP_CLOSEWINDOW: sys_exit(""); break;
}
}
if (mflag) update_movement(newx, newy);
}
void sys_handle_menu(menu_number)
unsigned short menu_number;
{
struct MenuItem *mi;
while (menu_number != MENUNULL)
{
mi = ItemAddress(head_menu, (long)menu_number);
handle_menu(MENUNUM(menu_number), ITEMNUM(menu_number), ((mi->Flags & CHECKED) > 0));
menu_number = mi->NextSelect;
}
}
void *sys_alloc(size)
unsigned int size;
{
return (void *)AllocMem((long)size, 0L);
}
void sys_free(ptr, size)
void *ptr;
unsigned int size;
{
FreeMem(ptr, (long)size);
}
char *sys_file_requestor(title, showpattern)
char *title;
char *showpattern; /* show only files matching this pattern */
{
answerarray[0] = 0;
/* Initialize the 'PathName' field so that the file requester will */
/* construct a complete path name for me. It will also put the two */
/* parts of the answer (directory and file name) into the directory */
/* file name which I also decided to supply it with. Since the */
/* directory and file name arrays are present, it will use their */
/* initial contents as the initial file and directory. If they aren't */
/* present it will leave both blank to start. */
MyFileReqStruct.PathName = answerarray;
MyFileReqStruct.Dir = directoryname;
MyFileReqStruct.File = filename;
MyFileReqStruct.Title = title;
/* The directory caching of this file requester is one of its nice */
/* features, so I decided to show it off. It is completely optional */
/* though, so if you don't want it, don't set this flag. If you do */
/* want it, don't forget to call PurgeFiles() when you are done. */
MyFileReqStruct.Flags = FRQCACHINGM;
/* Initialize a few colour fields. Not strictly necessary, but */
/* personally, I like having my files a different colour from my */
/* directories. */
MyFileReqStruct.dirnamescolor = 2;
MyFileReqStruct.devicenamescolor = 2;
MyFileReqStruct.numlines = 35;
strcpy(MyFileReqStruct.Show, showpattern);
/* I could also make it larger, pass it a file and/or directory */
/* name, set various flags and customize */
/* in many other ways, but I wanted to show that it can be easily */
/* used without having to fill in a lot of fields. */
if (FileRequester(&MyFileReqStruct))
return answerarray;
else
return (char *)0;
}
void sys_window(cols, rows, title)
int cols, rows;
char *title;
{
int width, height;
width = cols * font_w + 8;
height = rows * (font_h+3) + titlefont_h + 6 + 2;
newwindow.Flags =
WFLG_ACTIVATE |
WFLG_DRAGBAR |
WFLG_CLOSEGADGET |
WFLG_SMART_REFRESH |
WFLG_RMBTRAP; /* we won't have menus */
newwindow.IDCMPFlags =
IDCMP_GADGETDOWN |
IDCMP_MOUSEBUTTONS |
IDCMP_CLOSEWINDOW |
IDCMP_GADGETUP; /* we're only interested in gadgets */
newwindow.Width = width;
newwindow.Height = height;
newwindow.LeftEdge = (sxmax - width) / 2; /* centered on the screen */
newwindow.TopEdge = (symax - height) / 2;
newwindow.DetailPen = sys_medium; /* These are only used under 1.3 */
newwindow.BlockPen = sys_black;
newwindow.Title = title;
if ((window2 = OpenWindow(&newwindow)) == NULL)
sys_exit("unable to open second window");
rp2 = window2->RPort;
active_text = 0;
win2_mempoint = members;
}
void sys_close_window()
{
if (window2)
{
CloseWindow(window2);
window2 = NULL;
rp2 = NULL;
clear_remember(win2_mempoint);
}
}
void sys_say_text(str)
char *str;
{
int x, y;
int len = strlen(str);
if (!window2) return;
x = 6+(win2_col * font_w);
y = titlefont_h + 6 + (win2_row*(font_h+3)) + baseline;
Move(rp2, x, y);
SetAPen(rp2, sys_black);
Text(rp2, str, len);
win2_col += len; /* advance the cursor */
}
void sys_get_long(value, id)
long value;
int id;
{
int x, y, width;
if (!window2) return;
win2_col++;
x = 6+(win2_col * font_w);
y = titlefont_h + 6 + (win2_row*(font_h+3));
width = 8 * font_w;
add_long_gadget(window2, x, y, width, value, id, 1);
}
void sys_boolean(string, id)
char *string;
int id;
{
int x, y, len, width;
if (!window2) return;
x = 6+(win2_col * font_w);
y = titlefont_h + 6 + (win2_row*(font_h+3));
len = strlen(string);
width = len * font_w + 6; /* a few pixels on each side */
add_boolean_gadget(window2, x-3, y, width, string, 0, id, 1);
win2_col += (len + 1);
}
void sys_activate(id)
int id;
{
int success;
success = ActivateGadget(gadget_array[id], window2, 0L);
if (success) active_text = id;
}
void sys_movecur(col, row)
int col, row;
{
win2_row = row;
win2_col = col;
}
int sys_read_event(id, data)
int *id;
long *data;
{
ULONG class;
USHORT code;
struct Gadget *gadget;
struct IntuiMessage *message;
struct StringInfo *si;
int prev_active_text;
while (1)
{
Wait(1L<<window2->UserPort->mp_SigBit);
message = (struct IntuiMessage *)GetMsg(window2->UserPort);
class = message->Class;
code = message->Code;
gadget = (struct Gadget *)(message->IAddress);
ReplyMsg(message);
prev_active_text = active_text;
switch (class)
{
case IDCMP_MOUSEBUTTONS: /* we have to let the application know */
if (active_text)
sys_activate(active_text);
case IDCMP_GADGETDOWN: /* If the user presses on another gadget */
if (active_text)
{
*id = active_text;
si = (struct StringInfo *)(gadget_array[active_text]->SpecialInfo);
*data = si->LongInt;
}
if (class == IDCMP_GADGETDOWN)
{
if (gadget->GadgetType == GTYP_STRGADGET)
active_text = gadget->GadgetID;
}
if (prev_active_text) return EV_CHECKINT;
break;
case IDCMP_GADGETUP:
active_text = 0;
if (gadget->GadgetType == GTYP_BOOLGADGET)
{
*id = gadget->GadgetID;
*data = ((gadget->Flags & GFLG_SELECTED) > 0);
return EV_HITBUTTON;
}
else
{
*id = gadget->GadgetID;
si = (struct StringInfo *)(gadget->SpecialInfo);
*data = si->LongInt;
return EV_HITRETURN;
}
case IDCMP_CLOSEWINDOW:
return EV_CANCEL;
}
}
}
/* remember where we allocated memory, so that we can free
it easily later */
void *mem_alloc(bytes)
long bytes;
{
void *vapor; /* Vat a vapid vapor pointer! */
vapor = (void *)AllocMem(bytes, 0L);
remember_mem[members].memory = vapor;
remember_mem[members].bytes = bytes;
members++;
return vapor;
}
void clear_remember(to_where)
int to_where;
{
int mem;
for (mem = to_where; mem < members; mem++)
FreeMem(remember_mem[mem].memory, remember_mem[mem].bytes);
members = to_where;
}